package edu.scut.course_management.service;

import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import edu.scut.course_management.dao.DepartmentMapper;
import edu.scut.course_management.dao.MajorMapper;
import edu.scut.course_management.dao.RoleMapper;
import edu.scut.course_management.dao.StudentMapper;
import edu.scut.course_management.dao.TeacherMapper;
import edu.scut.course_management.dto.RequestStudentDTO;
import edu.scut.course_management.exception.CustomException;
import edu.scut.course_management.po.Department;
import edu.scut.course_management.po.Role;
import edu.scut.course_management.po.Student;
import edu.scut.course_management.po.Teacher;
import edu.scut.course_management.result.ResultCode;

@Service
public class PersonManagementService implements UserDetailsService {

    @Autowired
    private StudentMapper studentMapper;
    @Autowired
    private TeacherMapper teacherMapper;
    @Autowired
    private RoleMapper roleMapper;
    @Autowired 
    private DepartmentMapper departmentMapper;
    @Autowired
    private MajorMapper majorMapper;

    /**
     * Spring Security 框架使用
     * 用于查找登录用户是否为系统用户
    */
    @Override
    public UserDetails loadUserByUsername(String userId) throws UsernameNotFoundException {
        UserDetails user = studentMapper.findByStudentId(userId);
        if(user != null) {
            Role role = roleMapper.findByRoleId(((Student) user).getRoleId());
            ((Student) user).setRoles(role);
        } 
        else {
            user = teacherMapper.findByTeacherId(userId);
            if (user != null) {
                Role role = roleMapper.findByRoleId(((Teacher) user).getRoleId());
                ((Teacher) user).setRoles(role);
            }
        }
        return user;
    }

    /**
     * 管理员权限
     * 新增学生用户
     * @param Student
     */
    public void addStudentInfo (Student student) throws CustomException {
        if (isExistStudentAccount(student.getStudentId())) {
            throw new CustomException(ResultCode.USER_ACCOUNT_ALREADY_EXIST);
        }
        else {
            try {
                studentMapper.addStudent(student);
            }
            catch (DataAccessException e) {
                throw new CustomException(ResultCode.DATABASE_UPDATE_FAIL);
            }
        }
    }

    /**
     * 查询学生的帐号是否已经存在
     * @param studentId
     */
    public boolean isExistStudentAccount (String studentId) {
        Student student = studentMapper.findByStudentId(studentId);
        if (student != null) {
            return true;
        } else{
            return false;
        }
    }

    /**
     * 根据条件查询学生信息
     * @param conditions
     */
    public List<RequestStudentDTO> searchStudent (Map<String, Object> conditions) {
        return studentMapper.conditionalQuery(conditions);
    }

    /**
     * 根据学号查找学生
     * @param studentId
     */
    public Student findStudentById (String studentId) {
        return studentMapper.findByStudentId(studentId);
    }

    /**
     * 管理员权限
     * 更新学生信息
     * @param Student
     */
    public void modifiedStudent (Student student) throws CustomException {
        try {
            studentMapper.updateStudent(student);
        }
        catch (DataAccessException e) {
            throw new CustomException(ResultCode.DATABASE_UPDATE_FAIL);
        }
    }

    /**
     * 管理员权限
     * 删除学生信息
     * @param studentId
     */
    public void  deleteStudent (String studentId) throws CustomException {
        try {
            if (!isExistStudentAccount(studentId)) {
                throw new CustomException(ResultCode.USER_ACCOUNT_NOT_EXIST);
            }
            studentMapper.deleteStudent(studentId);
        } catch (DataAccessException e) {
            throw new CustomException(ResultCode.DATABASE_UPDATE_FAIL);
        }
    }

    /**
     * 重置学生密码
     */
    public void resetStudentPassword (String studentId) throws CustomException {
        
        Student student = studentMapper.findByStudentId(studentId);

        if (student == null) {
            throw new CustomException(ResultCode.USER_ACCOUNT_NOT_EXIST);
        }
        
        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        student.setPassword(passwordEncoder.encode(studentId));
        modifiedStudent(student);
    }


    /**
     * 修改学生账号密码
     * @param studentId,oldPassword,newPassword
     */
    public void modifiedStudentPassword (String studentId, String oldPassword, String newPassword) throws CustomException{
        
        Student student = studentMapper.findByStudentId(studentId);

        if (student == null) {
            throw new CustomException(ResultCode.USER_ACCOUNT_NOT_EXIST);
        }
        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        // 旧密码错误
        if(!passwordEncoder.matches(oldPassword, student.getPassword())) {
            throw new CustomException(ResultCode.USER_CREDENTIALS_ERROR);
        }
        // 更新密码
        student.setPassword(passwordEncoder.encode(newPassword));
        modifiedStudent(student);
    }

    /**
     * 管理员权限
     * 新增教师用户
     * @param Teacher
     */
    public void addTeacherInfo (Teacher teacher) throws CustomException {
        if (isExistTeacherAccount(teacher.getTeacherId())) {
            throw new CustomException(ResultCode.USER_ACCOUNT_ALREADY_EXIST);
        }
        else {
            try {
                teacherMapper.addTeacher(teacher);
            }
            catch (DataAccessException e) {
                throw new CustomException(ResultCode.DATABASE_UPDATE_FAIL);
            }
        }
    }

    /**
     * 查询教师的帐号是否已经存在
     * @param teacherId
     */
    public boolean isExistTeacherAccount (String teacherId) {
        Teacher teacher = teacherMapper.findByTeacherId(teacherId);
        if (teacher != null) {
            return true;
        } else{
            return false;
        }
    }

    /**
     * 根据条件查询教师信息
     * @param conditions
     */
    public List<Teacher> searchTeacher (Map<String, Object> conditions) {
        return teacherMapper.conditionalQuery(conditions);
    }

    /**
     * 根据工号查询教师信息
     * @param teacherId
     */
    public Teacher findTeacherById (String teacherId) {
        return teacherMapper.findByTeacherId(teacherId);
    }

    /**
     * 管理员权限
     * 更新教师信息
     * @param Teacher
     */
    public void modifiedTeacher (Teacher teacher) throws CustomException {
        try {
            teacherMapper.updateTeacher(teacher);
        }
        catch (DataAccessException e) {
            throw new CustomException(ResultCode.DATABASE_UPDATE_FAIL);
        }
    }

    /**
     * 管理员权限
     * 删除教师信息
     * @param teacherId
     */
    public void  deleteTeacher (String teacherId) throws CustomException {
        try {
            if (!isExistTeacherAccount(teacherId)) {
                throw new CustomException(ResultCode.USER_ACCOUNT_NOT_EXIST);
            }
            teacherMapper.deleteTeacher(teacherId);
        } catch (DataAccessException e) {
            throw new CustomException(ResultCode.DATABASE_UPDATE_FAIL);
        }
    }

    /**
     * 重置教师密码
     */
    public void resetTeacherPassword (String teacherId) throws CustomException {
        
        Teacher teacher = teacherMapper.findByTeacherId(teacherId);

        if (teacher == null) {
            throw new CustomException(ResultCode.USER_ACCOUNT_NOT_EXIST);
        }
        
        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        teacher.setPassword(passwordEncoder.encode(teacherId));
        modifiedTeacher(teacher);
    }

    /**
     * 修改教师账号密码
     * @param studentId,oldPassword,newPassword
     */
    public void modifiedTeacherPassword (String teacherId, String oldPassword, String newPassword) throws CustomException{
        
        Teacher teacher = teacherMapper.findByTeacherId(teacherId);

        if (teacher == null) {
            throw new CustomException(ResultCode.USER_ACCOUNT_NOT_EXIST);
        }
        BCryptPasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        // 旧密码错误
        if(!passwordEncoder.matches(oldPassword, teacher.getPassword())) {
            throw new CustomException(ResultCode.USER_CREDENTIALS_ERROR);
        }
        // 更新密码
        teacher.setPassword(passwordEncoder.encode(newPassword));
        modifiedTeacher(teacher);
    }

    /**
     * 查询院系名称
     * @param departmentId
     */
    public String findDepartmentById (Integer departmentId) {
        return departmentMapper.findByDepartmentId(departmentId).getDepartmentName();
    }

    /**
     * 查询专业名称
     * @param majorId
     */
    public String findMajorById (Integer majorId) {
        return majorMapper.findByMajorId(majorId).getMajorName();
    }

}
